package Controler;

import ChatNI.*;
import Model.ChatUser;
import Reseau.*;
import Vue.ChatGUI2;
import protocol.*;
import java.io.File;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.swing.DefaultListModel;

public class Controler {

    private Receive receive;
    private Send send;
    private SendTCP sendTcp;
    private String nomFichier;
    private File file;
    private InetAddress adressBroadcast;
    private DefaultListModel listUser;
    private DefaultListModel listUsername;
    private ChatUser userLocal;
    private boolean connecte;
    private ChatNI chatni;
    private ChatGUI2 chatgui;


    public Controler() {
        try {
            send = new Send(this);
            chatni = new ChatNI();
            listUser = new DefaultListModel();
            listUsername = new DefaultListModel();
            adressBroadcast = InetAddressUtil.getLocalBroadcast();
            connecte = false;
        } catch (UnknownHostException ex) {
            System.out.println("Erreur: création du controleur");
        }
    }

    public boolean isConnecte() {
        return connecte;
    }

    public ChatNI getChatni() {
        return chatni;
    }

    public ChatUser getUserLocal() {
        return userLocal;
    }
    
    public SendTCP getSendTcp() {
        return sendTcp;
    }

    public void setUserLocal(ChatUser p_userLocal) {
        this.userLocal = p_userLocal;
    }

    public DefaultListModel getListeUser() {
        return listUser;
    }

    public void setListeUser(DefaultListModel p_listUser) {
        this.listUser = p_listUser;
    }

    public DefaultListModel getListUsername() {
        return listUsername;
    }

    public void setListUsername(DefaultListModel listUsername) {
        this.listUsername = listUsername;
    }
    
    public void setChatgui(ChatGUI2 chatgui) {
        this.chatgui = chatgui;
    }

    public void connexion() {
        //On envoie un message Hello en broadcast
        receive = new Receive(this);
        Hello hello = new Hello(true, userLocal.getUsername(), userLocal.getAdresse());
        send.sendMessage(adressBroadcast, hello);
        System.out.println("J'ai envoyé ma demande de connexion");
        receive.setActif(true);
        receive.start();
        connecte=true;
    }

    public void deconnexion() {
        //On envoie un message Bye en broadcast et on vide tout
        receive.setActif(false);
        Bye bye = new Bye(userLocal.getUsername(), userLocal.getAdresse());
        send.sendMessage(adressBroadcast, bye);
        System.out.println("J'envoie un bye");
        //On vide la liste des users
        listUsername.clear();
        listUser.clear();
        connecte=false;
        chatgui.viderFenetre();
    }
    
    public void envoyerMessage(InetAddress addressDest, Message m){
        if(m instanceof FileNotify){
            file = chatgui.getFile();
            sendTcp = new SendTCP(file);
            sendTcp.start();   
        }
        System.out.println("J'envoie le message de chatmessage");
        send.sendMessage(addressDest, m);
    }
    
    public void attendreFichier(InetAddress _inet){
        //On crée un socket pour recevoir le fichier
        System.out.println("test04");
        ReceiveTCP receiveTcp = new ReceiveTCP(_inet);
        receiveTcp.start();
    }

    public void action(Message m, DatagramSocket ds) {
        System.out.println("J'ai recu un message!" + m);

        //Si ce n'es pas moi alors je traite
        if(!m.getSourceAddress().equals(userLocal.getAdresse())){
            if (m instanceof Hello) {
                System.out.println("J'ai reçu un hello");
                Hello h = (Hello) m;
                System.out.println("J'ajoute le user dans la liste " + m.getUsername());
                listUser.addElement(new ChatUser(m.getUsername(), m.getSourceAddress()));
                listUsername.addElement(m.getUsername());

                //si demande de réponse
                if (h.isRepreq() == true) {
                    System.out.println("Le hello demande une réponse");
                    Hello helloRetour = new Hello(false, userLocal.getUsername(), userLocal.getAdresse());
                    System.out.println("Je retourne un hello " + helloRetour);
                    send.sendMessage(h.getSourceAddress(), helloRetour);
                }
                
            } else if (m instanceof Bye) {
                System.out.println("J'ai recu un  bye");
                removeUser(m.getUsername());
                //On enlève l'utilisateur des onglets
                chatgui.enleverOnglet((Bye)m);
                
            } else if (m instanceof ChatMessage) {
                System.out.println("J'ai recu un chatMessage");
                chatgui.mettreAJourOnglet(m.getUsername(),((ChatMessage)m).getMessage(), false);
            }
            
            else if (m instanceof FileNotify){
                System.out.println("J'ai recu un fileNotify");
                //On me demande si je veux recevoir un fichier
                nomFichier = ((FileNotify)m).getNomFichier();
                System.out.println("test02");
                chatgui.creerFenetreFileNotify(nomFichier);
            }
            
            else if (m instanceof AckFile){
                System.out.println("J'ai recu un ackFile");
                //Si le user distant veut le fichier alors on lui envoie
                if(((AckFile)m).isAck()){
                    //On crée le socket pour envoyer le fichier
                    sendTcp = new SendTCP(chatgui.getFile());
                    sendTcp.start();
                }
            }
        }
    }

    public void removeUser(String p_username) {
        int r = 0;
        System.out.println("R = " + r);
        for (int i = 0; i < listUser.getSize(); i++) {
            System.out.println("User " + i + " " + ((ChatUser) listUser.getElementAt(i)).getUsername());
            if (p_username.compareTo(((ChatUser) listUser.get(i)).getUsername()) == 0) {
                r = i;
            }
        }
        listUser.removeElementAt(r);
        listUsername.removeElementAt(r);
    }

}
